home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_203 / examples / typeandtell / typeandtell.asm < prev    next >
Assembly Source File  |  1992-05-06  |  28KB  |  989 lines

  1. ;************************** TYPE and TELL ****************************
  2. ;
  3. ; Original C Code By: Giorgio Galeotti
  4. ;
  5. ; Anakin Research Inc.
  6. ; Rexdale, Ontatio, Canada.
  7. ; Tel. 416-744-4246
  8. ;
  9. ; Assembly version by Jeff Glatt. Needs to be linked with a startup code.
  10. ;
  11. ; This program will install an input device handler before the Intuition one,
  12. ; inspect all keys typed by the user and spell them out in real time.
  13. ;
  14. ; Just run this program as a background task. To quit the program, press:
  15. ; "CONTROL LEFT-SHIFT LEFT-ALT RIGHT-AMIGA" at the same time.
  16.  
  17.    XREF   _CreateExtIO,_DeleteExtIO  ;Standard C functions (use the 32 bit
  18.    XREF   _CreateStdIO,_DeleteStdIO  ;versions only)
  19.    XREF   _CreatePort,_DeletePort
  20.  
  21.    XREF   _LVOWaitTOF                ;Amiga.lib _LVO labels
  22.    XREF   _LVOTranslate
  23.    XREF   _LVODoIO
  24.    XREF   _LVORawKeyConvert
  25.    XREF   _LVOWait,_LVOSignal
  26.    XREF   _LVOAllocSignal,_LVOFreeSignal
  27.    XREF   _LVOOpenLibrary,_LVOCloseLibrary
  28.    XREF   _LVOOpenDevice,_LVOCloseDevice
  29.  
  30.    XREF   _SysBase,_DOSBase,_exit,_ThisTask  ;From SmallStart.asm
  31.  
  32.    SECTION TypeTellCode,CODE
  33.  
  34. LIB_VERSION equ 33
  35.  
  36.    XDEF   _main
  37. _main:
  38.     movea.l  _SysBase,a6
  39. ;Open the console device with unit = -1. This will return an IOBlock
  40. ;with the io_Device field initialized to the Console device base.
  41. ;See page B-27 of "Libraries and Devices" console.device/OpenDevice
  42.     moveq   #0,d1
  43.     movea.l _InputRequestBlock,a1
  44.     moveq   #-1,d0         ;don't actually open a console
  45.     lea     ConsoleName,a0
  46.     jsr     _LVOOpenDevice(a6)
  47.     move.l  d0,d1
  48.     beq.s   .4             ;branch if no error
  49.  ;---Exit with error 100
  50.     pea     100
  51.     jsr     _exit
  52.  ;---Get the address of Console Device's base structure
  53. .4  lea      _InputRequestBlock,a0
  54.     movea.l  (a0),a1
  55.     move.l   20(a1),_ConsoleDevice
  56.   ;---InputRequestBlock pointer = 0 (For clean up purposes)
  57.     clr.l    (a0)
  58.   ;---Close the console device
  59.     jsr      _LVOCloseDevice(a6)
  60. ;Open the Graphics library, since it's needed to do the WaitTOF()
  61. ;calls in the input handler
  62.     moveq   #LIB_VERSION,d0
  63.     lea     GfxName,a1
  64.     jsr     _LVOOpenLibrary(a6)
  65.     move.l   d0,_GfxBase
  66.     bne.s   .5
  67.  ;---Exit with error 110
  68.     moveq    #110,d0
  69.     bra      _CleanUp_Exit
  70.  ;---Get a signal bit so that our input handler can wake us up
  71.  ;---when there is something in the buffer
  72. .5  moveq    #-1,d0
  73.     jsr      _LVOAllocSignal(a6)
  74.     move.b   d0,_MainSignal
  75.     bpl.s    .SS
  76.  ;---Exit with error 115
  77.     moveq    #115,d0
  78.     bra      _CleanUp_Exit
  79.  ;---Make a mask of the signal
  80. .SS moveq    #0,d1
  81.     Bset.l   d0,d1
  82.     move.l   d1,MainSigMask
  83.   ;---get the address of our MainTask
  84.   ;  suba.l   a1,a1            ;SmallStart.asm does this already. If you
  85.   ;  jsr      _LVOFindTask(a6) ;aren't using it, uncomment this and create
  86.   ;  move.l   d0,_ThisTask     ;a LONG variable, _ThisTask.
  87.   ;---Get a port for the input device
  88.     clr.l    -(sp)
  89.     clr.l    -(sp)
  90.     jsr      _CreatePort
  91.     addq.w   #8,sp
  92.     move.l   d0,_InputDevPort
  93.     bne.s    .6
  94.   ;---Exit with error 120
  95.     moveq    #120,d0
  96.     bra      _CleanUp_Exit
  97.  ;---Get an InputRequestBlock
  98. .6  move.l   d0,-(sp)
  99.     jsr      _CreateStdIO
  100.     addq.w   #4,sp
  101.     move.l   d0,_InputRequestBlock
  102.     bne.s   .7
  103.  ;---Exit with error 130
  104.     moveq    #0,d0
  105.     move.b   #130,d0
  106.     bra      _CleanUp_Exit
  107. ;============Open the input device==============
  108. .7  moveq   #0,d1
  109.     movea.l d0,a1
  110.     moveq   #0,d0
  111.     lea     InputName,a0
  112.     jsr     _LVOOpenDevice(a6)
  113.     move.l  d0,d1
  114.     bne.s   .8
  115.     Bset.b  #0,DevicesOpen
  116.     bra.s   .9
  117.   ;---Exit with error 140
  118. .8  moveq    #0,d0
  119.     move.b   #140,d0
  120.     bra      _CleanUp_Exit
  121. ;========Get ready to install our own input device handler===========
  122.   ;---InputRequestBlock's io_Command = IND_ADDHANDLER
  123. .9  movea.l  _InputRequestBlock,a1
  124.     moveq    #9,d0
  125.     move.w   d0,28(a1)
  126.   ;---InputRequestBlock's io_Data = the address of handlerInt structure
  127.     move.l   #handlerInt,40(a1)
  128. ;-----Install the handler
  129.     jsr      _LVODoIO(a6)
  130. ;==============Open the translator library==============
  131.     moveq    #LIB_VERSION,d0
  132.     lea      TransName,a1
  133.     jsr      _LVOOpenLibrary(a6)
  134.     move.l   d0,_TranslatorBase
  135.     bne.s    .10
  136.   ;---Exit with error 500
  137.     moveq    #0,d0
  138.     move.w   #500,d0
  139.     bra      _CleanUp_Exit
  140. ;===========Open the Narrator device for writes==========
  141.   ;---Get a WritePort
  142. .10 clr.l    -(sp)
  143.     clr.l    -(sp)
  144.     jsr      _CreatePort
  145.     addq.w   #8,sp
  146.     move.l   d0,_WritePort
  147.     bne.s    .11
  148.   ;---Exit with error 510
  149.     moveq    #0,d0
  150.     move.w   #510,d0
  151.     bra      _CleanUp_Exit
  152.   ;---Get an IOB, WriteNarrator
  153. .11 pea      70
  154.     move.l   d0,-(sp)
  155.     jsr      _CreateExtIO
  156.     addq.w   #8,sp
  157.     move.l   d0,_WriteNarrator
  158.     bne.s    .12
  159.   ;---Exit with error 520
  160.     moveq    #0,d0
  161.     move.w   #520,d0
  162.     bra      _CleanUp_Exit
  163.   ;---Open the Narrator device
  164. .12 moveq    #0,d1
  165.     movea.l  d0,a1
  166.     moveq    #0,d0
  167.     lea      NarrDevName,a0
  168.     jsr      _LVOOpenDevice(a6)
  169.     move.l   d0,d1
  170.     bne.s    .13
  171.     Bset.b   #1,DevicesOpen
  172.     bra.s    .14
  173.   ;---Exit with error 140
  174. .13 moveq    #0,d0
  175.     move.b   #140,d0
  176.     bra      _CleanUp_Exit
  177. ;=====Set up part of the narrator's IOB (the fields that never change)=====
  178. .14 movea.l  _WriteNarrator,a1
  179.   ;---io_Command = CMD_WRITE
  180.     moveq    #3,d0
  181.     move.w   d0,28(a1)
  182.   ;---WriteNarrator's rate     = DEFRATE+100
  183.     moveq    #0,d0
  184.     move.b   #250,d0
  185.     move.w   d0,48(a1)
  186.   ;---ch_masks  = AudioChannels
  187.     lea      56(a1),a0
  188.     move.l   #_AudioChannels,(a0)+     ;56(IOB)
  189.   ;---nm_masks  = sizeof AudioChannels
  190.     moveq    #4,d0
  191.     move.w   d0,(a0)+                  ;60(IOB)
  192.   ;---WriteNarrator's volume   = DEFVOL
  193.     moveq    #64,d0
  194.     move.w   d0,(a0)+                  ;62(IOB)
  195.   ;--WriteNarrator's sampfreq = DEFFREQ
  196.     move.w   #22200,(a0)               ;64(IOB)
  197.  
  198. ;Do the main control routine and sit there until the user requests to quit
  199.  
  200. ;This routine contains the loop that keeps checking everything the user does
  201. ;at the keyboard so that appropriate actions can be taken.
  202. ;  actual = # of bytes returned by RawKeyConvert
  203. ;  buffer = Buffer used by RawKeyConvert() to put results in
  204.  
  205.    XDEF   TheBigLoop
  206. TheBigLoop:
  207.   ;----if Counter is not 0, then something is in the buffer
  208.     move.b    Counter,d0
  209.     bne.s     .21
  210.   ;---Otherwise, sleep til signalled
  211. SLP movea.l   _SysBase,a6
  212.     move.l    MainSigMask,d0
  213.     Bset.b    #0,_Waiting     ;indicate "main is asleep" to event_handler()
  214.     jsr       _LVOWait(a6)
  215.     and.l     MainSigMask,d0
  216.     beq.s     SLP
  217.   ;---Get our last position in the buffer
  218. .21 moveq     #22,d1
  219.     move.w    _Emptier,d0
  220.     mulu.w    d1,d0
  221.     lea       _EventRing,a0
  222.     adda.l    d0,a0
  223. ;=======Check if user requested to quit Type&Tell=======
  224. ; if Event's ie_Qualifier is QUIT_CODE_1 OR QUIT_CODE_2
  225. ; then CleanUp_Exit(1000)
  226.     move.w    8(a0),d1
  227.     subi.w    #QUIT_CODE_1,d1
  228.     beq.s     .23
  229.     subi.w    #QUIT_CODE_2-QUIT_CODE_1,d1
  230.     bne.s     .22
  231. .23 moveq     #0,d0
  232.     move.w    #1000,d0
  233.     bra       _CleanUp_Exit  ;never returns
  234. ;Convert raw-key event to ANSI standard. Assume default keymap.
  235. ;actual = RawKeyConvert(&EventRing[Emptier],buffer,30,0)
  236. .22 move.l    a2,-(sp)
  237.     suba.l    a2,a2           ;no keymap, use default
  238.     moveq     #30,d1
  239.     lea       rawkeyBuf,a1
  240.     ;current EventRing address in a0
  241.     move.l    a0,-(sp)
  242.     movea.l   _ConsoleDevice,a6
  243.     jsr       _LVORawKeyConvert(a6)
  244.     movea.l   (sp)+,a1
  245.     movea.l   (sp)+,a2
  246.   ;if actual is 1 (a simple ascii char) then do SpeakASCII(buffer)
  247.     lea       rawkeyBuf,a0
  248.     subq.l    #1,d0
  249.     beq       SpeakASCII
  250.   ;--else SpeakQualifier( EventRing's Address ) more than 1 char in the
  251.   ;  buffer, must be a control sequence.
  252.     ; Fall through to SpeakQualifier
  253. ;***************************************************
  254. ;SpeakQualifier(Event)
  255. ;                a1
  256. ; The keystroke did not translate to any single ASCII character,
  257. ; but nevertheless, it must be called out.
  258.  
  259.    XDEF   SpeakQualifier
  260. SpeakQualifier:
  261.     movea.l  _WriteNarrator,a0
  262.     adda.w   #50,a0
  263.   ;---WriteNarrator's pitch    = DEFPITCH+100
  264.     moveq    #0,d0
  265.     move.b   #210,d0
  266.     move.w   d0,(a0)+
  267.   ;---WriteNarrator's mode     = NATURALF0
  268.     clr.w    (a0)+
  269.   ;---WriteNarrator's sex      = FEMALE
  270.     moveq    #1,d0
  271.     move.w   d0,(a0)
  272. ;---do a switch on the passed Rawkey Event's ie_Code field---
  273.     move.w   6(a1),d0
  274.     subi.w   #76,d0
  275.     beq      .102
  276.     subq.w   #1,d0
  277.     beq      .105
  278.     subq.w   #1,d0
  279.     beq      .104
  280.     subq.w   #1,d0
  281.     beq      .103
  282.     subq.w   #1,d0
  283.     beq.s    .84
  284.     subq.w   #1,d0
  285.     beq      .85
  286.     subq.w   #1,d0
  287.     beq      .86
  288.     subq.w   #1,d0
  289.     beq      .87
  290.     subq.w   #1,d0
  291.     beq      .88
  292.     subq.w   #1,d0
  293.     beq      .89
  294.     subq.w   #1,d0
  295.     beq      .90
  296.     subq.w   #1,d0
  297.     beq      .91
  298.     subq.w   #1,d0
  299.     beq      .92
  300.     subq.w   #1,d0
  301.     beq      .93
  302.     subq.w   #6,d0
  303.     beq      .101
  304.     subq.w   #1,d0
  305.     beq      .95
  306.     subq.w   #1,d0
  307.     beq      .95
  308.     subq.w   #1,d0
  309.     beq      .106
  310.     subq.w   #1,d0
  311.     beq      .94
  312.     subq.w   #1,d0
  313.     beq      .97
  314.     subq.w   #1,d0
  315.     beq      .97
  316.     subq.w   #1,d0
  317.     beq      .99
  318.     subq.w   #1,d0
  319.     beq      .100
  320.     subi.w   #123,d0
  321.     beq      .107
  322.     bra      .25
  323. ; case 0x50: Translate("FUNCTION 1",10,OutputString,100)
  324. .84 moveq    #12,d0
  325.     lea      F1,a0
  326.     bra      .40
  327. ; case 0x51: Translate("FUNCTION 2",10,OutputString,100)
  328. .85 moveq    #12,d0
  329.     lea      F2,a0
  330.     bra      .40
  331. ; case 0x52: Translate("FUNCTION 3",10,OutputString,100)
  332. .86 moveq    #14,d0
  333.     lea      F3,a0
  334.     bra      .40
  335. ; case 0x53: Translate("FUNCTION 4",10,OutputString,100)
  336. .87 moveq    #13,d0
  337.     lea      F4,a0
  338.     bra      .40
  339. ; case 0x54: Translate("FUNCTION 5",10,OutputString,100)
  340. .88 moveq    #13,d0
  341.     lea      F5,a0
  342.     bra      .40
  343. ; case 0x55: Translate("FUNCTION 6",10,OutputString,100)
  344. .89 moveq    #12,d0
  345.     lea      F6,a0
  346.     bra      .40
  347. ; case 0x56: Translate("FUNCTION 7",10,OutputString,100)
  348. .90 moveq    #14,d0
  349.     lea      F7,a0
  350.     bra      .40
  351. ; case 0x57: Translate("FUNCTION 8",10,OutputString,100)
  352. .91 moveq    #14,d0
  353.     lea      F8,a0
  354.     bra      .40
  355. ; case 0x58: Translate("FUNCTION 9",10,OutputString,100)
  356. .92 moveq    #13,d0
  357.     lea     F9,a0
  358.     bra     .40
  359. ; case 0x59: Translate("FUNCTION TEN",12,OutputString,100)
  360. .93 moveq   #12,d0
  361.     lea     F10,a0
  362.     bra     .40
  363. ; case 0x63: Translate("CONTROL",7,OutputString,100)
  364. .94 moveq   #7,d0
  365.     lea     CONTROL,a0
  366.     bra     .40
  367. ;case 0x60 or 0x61: Translate("SHIFT",5,OutputString,100)
  368. .95 moveq   #5,d0
  369.     lea     SHIFT,a0
  370.     bra     .40
  371. ; case 0x65: Translate("ALTERNATE",9,OutputString,100)
  372. .97 moveq   #9,d0
  373.     lea     ALTERNATE,a0
  374.     bra     .40
  375. ; case 0x66: Translate("LEFT AMIGA",10,OutputString,100)
  376. .99 moveq   #10,d0
  377.     lea     LEFTAMG,a0
  378.     bra     .40
  379. ; case 0x67: Translate("RIGHT AMIGA",11,OutputString,100)
  380. .100 moveq   #11,d0
  381.      lea     RIGHTAMG,a0
  382.      bra     .40
  383. ;case 0x5f: Translate("HELP",4,OutputString,100)
  384. .101 moveq   #4,d0
  385.      lea     HELP,a0
  386.      bra     .40
  387. ; case 0x4c: Translate("GO UP",5,OutputString,100)
  388. .102 moveq   #5,d0
  389.      lea     GOUP,a0
  390.      bra     .40
  391. ; case 0x4f: Translate("GO LEFT",7,OutputString,100)
  392. .103 moveq   #7,d0
  393.      lea     GOLEFT,a0
  394.      bra     .40
  395. ; case 0x4e: Translate("GO RIGHT",8,OutputString,100)
  396. .104 moveq   #8,d0
  397.      lea     GORIGHT,a0
  398.      bra     .40
  399. ; case 0x4d: Translate("GO DOWN",7,OutputString,100)
  400. .105 moveq   #7,d0
  401.      lea     GODOWN,a0
  402.      bra     .40
  403. ; case 0x62: Translate("CAPS LOCK ON",12,OutputString,100)
  404. .106 moveq   #12,d0
  405.      lea     CAPSON,a0
  406.      bra     .40
  407. ; case 0xe2: Translate("CAPS LOCK OFF",13,OutputString,100)
  408. .107 moveq   #13,d0
  409.      lea     CAPSOFF,a0
  410.      bra     .40
  411.  
  412. ;******************************************************
  413. ;SpeakASCII(inputbuffer)
  414. ;               a0
  415. ;
  416. ;Speak the ASCII character contained in buffer.
  417.  
  418.    XDEF   SpeakASCII
  419. SpeakASCII:
  420.      movea.l  _WriteNarrator,a1
  421.  ;---Check if the char is 'A' to 'Z' or '0' to '9'
  422.      move.b   (a0),d0
  423.      cmpi.b   #'A',d0
  424.      bcs.s    .34
  425.      cmpi.b   #'Z',d0
  426.      bls.s    .33
  427. .34  cmpi.b   #'0',d0
  428.      bcs.s    .32
  429.      cmpi.b   #'9',d0
  430.      bhi.s    .32
  431.  ;---If so....
  432.   ;---WriteNarrator's pitch    = DEFPITCH
  433. .33  moveq    #110,d1
  434.      move.w   d1,50(a1)
  435.   ;---WriteNarrator's mode     = NATURALF0
  436.      clr.w    52(a1)
  437.   ;---WriteNarrator's sex      = MALE
  438.      clr.w    54(a1)
  439.   ;---Translate(buffer,1,OutputString,100) translate the char
  440.      moveq    #1,d0
  441.      bra      .40
  442. ;======================================
  443.  ;---Check if the char is 'a' to 'z'
  444. .32  cmpi.b   #'a',d0
  445.      bcs.s    .36
  446.      cmpi.b   #'z',d0
  447.      bhi.s    .36
  448.   ;---WriteNarrator's pitch    = DEFPITCH+50
  449.      move.b   #160,d1
  450.      move.w   d1,50(a1)
  451.   ;---WriteNarrator's mode     = NATURALF0
  452.      clr.w    52(a1)
  453.   ;---WriteNarrator's sex      = FEMALE
  454.      moveq    #1,d0
  455.      move.w   d0,54(a1)
  456.      bra      .40
  457. ;=====OTHERWISE, USE THE FOLLOWING SETTINGS=========
  458.   ;---WriteNarrator's pitch    = DEFPITCH
  459. .36  moveq    #110,d1
  460.      move.w   d1,50(a1)
  461.   ;---WriteNarrator's mode     = NATURALF0
  462.      clr.w    52(a1)
  463.   ;---WriteNarrator's sex      = MALE
  464.      clr.w    54(a1)
  465. ;========See if it is a control character ($01 to $1A)=======
  466.      cmpi.b   #1,d0
  467.      bcs      .25
  468.      move.b   d0,d1
  469.      subi.b   #$1B,d0
  470.      bcc.s    .37
  471.    ;-----copy "CONTROL" to buffer
  472.      lea      CONTROL,a1
  473.      move.l   a0,d0       ;save buffer address
  474. CStr move.b   (a1)+,(a0)+
  475.      bne.s    CStr
  476.    ;---add a space at the end of CONTROL
  477.      move.b   #' ',-1(a0)
  478.      addi.b   #$40,d1     ;convert to ascii letter
  479.      move.b   d1,(a0)
  480.    ;Translate(buffer,9,OutputString,100)
  481.      movea.l  d0,a0
  482.      moveq    #9,d0
  483.      bra      .40
  484. ;=========else switch on the character===========
  485. .37  beq      .41       ;ESC
  486.      subq.b   #5,d0
  487.      beq      .42       ;SPACE
  488.      subq.b   #1,d0
  489.      beq      .43       ;!
  490.      subq.b   #1,d0
  491.      beq      .44       ;"
  492.      subq.b   #1,d0
  493.      beq      .45       ;#
  494.      subq.b   #1,d0
  495.      beq      .46       ;$
  496.      subq.b   #1,d0
  497.      beq      .47       ;%
  498.      subq.b   #1,d0
  499.      beq      .48       ;&
  500.      subq.b   #1,d0
  501.      beq      .49       ;'
  502.      subq.b   #1,d0
  503.      beq      .50       ;(
  504.      subq.b   #1,d0
  505.      beq      .51       ;)
  506.      subq.b   #1,d0
  507.      beq      .52       ;*
  508.      subq.b   #1,d0
  509.      beq      .53       ;+
  510.      subq.b   #1,d0
  511.      beq      .54       ;,
  512.      subq.b   #1,d0
  513.      beq      .55       ;-
  514.      subq.b   #1,d0
  515.      beq      .56       ;.
  516.      subq.b   #1,d0
  517.      beq      .57       ;/
  518.      subi.b   #11,d0
  519.      beq      .58       ;:
  520.      subq.b   #1,d0
  521.      beq      .59       ;;
  522.      subq.b   #1,d0
  523.      beq      .60       ;<
  524.      subq.b   #1,d0
  525.      beq      .62       ;=
  526.      subq.b   #1,d0
  527.      beq      .61       ;>
  528.      subq.b   #1,d0
  529.      beq      .63       ;?
  530.      subq.b   #1,d0
  531.      beq      .64       ;@
  532.      subi.b   #27,d0
  533.      beq      .65       ;[
  534.      subq.b   #1,d0
  535.      beq      .66       ;\
  536.      subq.b   #1,d0
  537.      beq      .67       ;]
  538.      subq.b   #1,d0
  539.      beq      .68       ;^
  540.      subq.b   #1,d0
  541.      beq      .69       ;_
  542.      subq.b   #1,d0
  543.      beq      .70       ;
  544.      subi.b   #27,d0
  545.      beq      .71       ;{
  546.      subq.b   #1,d0
  547.      beq      .72       ;|
  548.      subq.b   #1,d0
  549.      beq      .73       ;}
  550.      subq.b   #1,d0
  551.      beq      .74       ;TILDA
  552.      subq.b   #1,d0
  553.      beq      .75       ;DEL
  554.      bra      .25       ;rts if not any of these (what is it???)
  555. ; case 0x1b: "ESCAPE"
  556. .41  moveq    #6,d0
  557.      lea      ESCAPE,a0
  558.      bra      .40
  559. ; case ' ': "SPACE"
  560. .42  moveq    #5,d0
  561.      lea      SPACE,a0
  562.      bra      .40
  563. ; case '!': "EXCLAMATION"
  564. .43  moveq    #11,d0
  565.      lea      EXCLAM,a0
  566.      bra      .40
  567. ; case '"': "DOUBLE QUOTE"
  568. .44  moveq    #12,d0
  569.      lea      DQ,a0
  570.      bra      .40
  571. ; case '#': "SHARP"
  572. .45  moveq    #5,d0
  573.      lea      SHARP,a0
  574.      bra      .40
  575. ; case '$': "DOLLAR"
  576. .46  moveq    #6,d0
  577.      lea      DOLLAR,a0
  578.      bra      .40
  579. ; case '%': "PERCENT"
  580. .47  moveq    #7,d0
  581.      lea      PERCENT,a0
  582.      bra      .40
  583. ; case '&': "AND"
  584. .48  moveq    #3,d0
  585.      lea      AND,a0
  586.      bra      .40
  587. ; case '\'': "RIGHT QUOTE"
  588. .49  moveq    #11,d0
  589.      lea      RQUOTE,a0
  590.      bra     .40
  591. ; case '(': "LEFT PARENTHESIS"
  592. .50  moveq    #16,d0
  593.      lea      LP,a0
  594.      bra      .40
  595. ; case ')': "RIGHT PARENTHESIS"
  596. .51  moveq    #17,d0
  597.      lea      RP,a0
  598.      bra      .40
  599. ; case '*': "STAR"
  600. .52  moveq    #4,d0
  601.      lea      STAR,a0
  602.      bra      .40
  603. ; case '+': "PLUS"
  604. .53  moveq    #4,d0
  605.      lea      PLUS,a0
  606.      bra      .40
  607. ; case ',': "COMMA"
  608. .54  moveq    #5,d0
  609.      lea      COMMA,a0
  610.      bra      .40
  611. ; case '-': "MYNUS"
  612. .55  moveq    #5,d0
  613.      lea      MYNUS,a0
  614.      bra      .40
  615. ; case '.': "DOT"
  616. .56  moveq    #3,d0
  617.      lea      DOT,a0
  618.      bra      .40
  619. ; case '/': "SLASH"
  620. .57  moveq    #5,d0
  621.      lea      SLASH,a0
  622.      bra      .40
  623. ; case ':': "COLON"
  624. .58  moveq    #5,d0
  625.      lea      COLON,a0
  626.      bra      .40
  627. ; case ';': "SEMI COLON"
  628. .59  moveq    #10,d0
  629.      lea      SCOLON,a0
  630.      bra      .40
  631. ; case '<': "LESS THAN"
  632. .60  moveq    #9,d0
  633.      lea      LESS,a0
  634.      bra      .40
  635. ; case '>': "GREATER THAN"
  636. .61  moveq    #12,d0
  637.      lea      GREAT,a0
  638.      bra      .40
  639. ; case '=': "EQUAL"
  640. .62  moveq    #5,d0
  641.      lea      EQUAL,a0
  642.      bra      .40
  643. ; case '?': "QUESTION"
  644. .63  moveq    #8,d0
  645.      lea      QUES,a0
  646.      bra.s    .40
  647. ; case '@': "AT"
  648. .64  moveq    #2,d0
  649.      lea      AT,a0
  650.      bra.s    .40
  651. ; case '[': "LEFT BRACKET"
  652. .65  moveq    #12,d0
  653.      lea      LBRACK,a0
  654.      bra.s    .40
  655. ; case '\\': "BACKSLASH"
  656. .66  moveq    #9,d0
  657.      lea      BSLASH,a0
  658.      bra.s    .40
  659. ; case ']': "RIGHT BRACKET"
  660. .67  moveq    #13,d0
  661.      lea      RBRACK,a0
  662.      bra.s    .40
  663. ; case '^': "CARROT"
  664. .68  moveq    #6,d0
  665.      lea      CARROT,a0
  666.      bra.s    .40
  667. ; case '_': "UNDER SCORE"
  668. .69  moveq    #11,d0
  669.      lea      SCORE,a0
  670.      bra.s    .40
  671. ; case '`': "LEFT QUOTE"
  672. .70  moveq    #10,d0
  673.      lea      LQUOTE,a0
  674.      bra.s    .40
  675. ; case '{': "LEFT BRACE"
  676. .71  moveq    #10,d0
  677.      lea      LBRACE,a0
  678.      bra.s    .40
  679. ; case '|': "VERTICAL BAR"
  680. .72  moveq    #12,d0
  681.      lea      VBAR,a0
  682.      bra.s    .40
  683. ; case '}': "RIGHT BRACE"
  684. .73  moveq    #11,d0
  685.      lea      RBRACE,a0
  686.      bra.s    .40
  687. ; case '~': "TILDA"
  688. .74  moveq    #5,d0
  689.      lea      TILDA,a0
  690.      bra.s    .40
  691. ; case $7f: "DELETE"
  692. .75  moveq    #6,d0
  693.      lea      DEL,a0
  694. .40  movea.l  _TranslatorBase,a6
  695.      moveq    #100,d1
  696.      lea      _OutputString,a1
  697.      jsr      _LVOTranslate(a6)
  698.   ;---WriteNarrator's io_Data = address of OutputString
  699. DOIT lea      _OutputString,a0
  700.      movea.l  _WriteNarrator,a1
  701.      move.l   a0,40(a1)
  702.      move.l   a0,d0
  703.   ;---WriteNarrator's io_Length = length of OutputString
  704. CNT  move.b   (a0)+,d1
  705.      bne.s    CNT
  706.      subq.l   #1,a0
  707.      sub.l    d0,a0
  708.      move.l   a0,36(a1)
  709.   ;----And speak it
  710.      movea.l  _SysBase,a6
  711.      jsr      _LVODoIO(a6)
  712. ;===============================================
  713.   ;---indicate one less event in the buffer
  714. .25  subq.b   #1,Counter
  715.   ;---Check for Buffer wrap
  716.      addq.w   #1,_Emptier
  717.      moveq    #50,d0
  718.      sub.w    _Emptier,d0
  719.      bhi      TheBigLoop   ;back to main loop
  720.      clr.w    _Emptier
  721.      bra      TheBigLoop
  722.  
  723. ;**************************************************************
  724. ; Clean up all allocated resources and exit
  725.  
  726.    XDEF   _CleanUp_Exit
  727. _CleanUp_Exit:
  728.      move.l   d0,-(sp)     ;push return code
  729.      movea.l  _SysBase,a6
  730. ;=======Remove our input handler and device from the chain======
  731.      move.l   _InputRequestBlock,d0
  732.      beq.s    .115
  733.   ;---InputRequestBlock's io_Command = IND_REMHANDLER
  734.      movea.l  d0,a1
  735.      moveq    #10,d0
  736.      move.w   d0,28(a1)
  737.   ;---InputRequestBlock's io_Data = address of handlerInt
  738.      move.l   #handlerInt,40(a1)
  739.      jsr      _LVODoIO(a6)
  740.    ;----Close Input Device
  741.      Bclr.b   #0,DevicesOpen
  742.      beq.s    .116
  743.      movea.l  _InputRequestBlock,a1
  744.      jsr      _LVOCloseDevice(a6)
  745.   ;---Free the main signal
  746. .116 move.b   _MainSignal,d0
  747.      bmi.s    .FS
  748.      jsr      _LVOFreeSignal(a6)
  749.    ;----DeleteStdIO InputRequestBlock
  750. .FS  move.l   _InputRequestBlock,-(sp)
  751.      jsr      _DeleteStdIO
  752.      addq.w   #4,sp
  753.    ;----DeletePort InputDevPort
  754. .115 move.l   _InputDevPort,d0
  755.      beq.s    .117
  756.      move.l   d0,-(sp)
  757.      jsr      _DeletePort
  758.      addq.w   #4,sp
  759.    ;-----Close Narrator Device
  760. .117 Bclr.b   #1,DevicesOpen
  761.      beq.s    .118
  762.      movea.l  _WriteNarrator,a1
  763.      jsr      _LVOCloseDevice(a6)
  764.    ;----DeleteExtIO WriteNarrator
  765. .118 move.l   _WriteNarrator,d0
  766.      beq.s    .119
  767.      pea      70
  768.      move.l   d0,-(sp)
  769.      jsr      _DeleteExtIO
  770.      addq.w   #8,sp
  771.    ;----Close Translator library
  772. .119 move.l   _TranslatorBase,d0
  773.      beq.s    .120
  774.      movea.l  d0,a1
  775.      jsr      _LVOCloseLibrary(a6)
  776.   ;----DeletePort WritePort
  777. .120 move.l   _WritePort,d0
  778.      beq.s    .121
  779.      move.l   d0,-(sp)
  780.      jsr      _DeletePort
  781.      addq.w   #4,sp
  782.   ;----Close Graphics
  783. .121 move.l   _GfxBase,d0
  784.      beq.s    .122
  785.      movea.l  d0,a1
  786.      jsr      _LVOCloseLibrary(a6)
  787. .122 jsr      _exit
  788.  
  789. ;*****************************************************************
  790. ; InputEvent = myhandler(EventChain,ISDATA)
  791. ;    d0                      a0       a1
  792. ; This input handler inserts itself at a higher priority than the Intuition
  793. ; handler. It will intercept all raw-key events and put them into the
  794. ; ringbuffer, EventRing, so that the main task's big_loop can use the data to
  795. ; keep track of what keys have been pressed by the user.
  796. ; This looks at all events in the EventChain and puts in the buffer all
  797. ; raw-key events whose time stamp indicates that we haven't looked at them
  798. ; before. Hopefully the system links new events at the end of the chain, so
  799. ; that all time stamps are in order.
  800.  
  801. TDNestCnt equ 295
  802.    XREF   _LVOPermit
  803.  
  804.    XDEF   event_handler
  805. event_handler:
  806.      movem.l  a0/a2/a3/a6,-(sp)
  807.      movea.l  a1,a3       ;save ISDATA (currentBuf)
  808.   ;---Forbid
  809.      movea.l  _SysBase,a6
  810.   ;   addq.b   #1,TDNestCnt(a6)
  811.   ;---Get the first InputEvent in EventChain
  812.      movea.l  a0,a2
  813.   ;---Check if Event's ie_Class = IECLASS_RAWKEY
  814. .128 move.b   4(a2),d0
  815.      subq.b   #1,d0
  816.      bne.s    .129         ;if not, ignore it
  817. ; if Event's ie_TimeStamp.tv_micro > lastmicro AND
  818. ; Event's ie_TimeStamp.tv_secs >= lastsecond  OR
  819. ; Event's ie_TimeStamp.tv_secs >  lastsecond
  820.      move.l   18(a2),d0
  821.      move.l   14(a2),d1
  822.      cmp.l    6(a3),d1    ;lastsecond
  823.      bcs.s    .129
  824.      bne.s    .131
  825.      cmp.l    10(a3),d0   ;lastmicro
  826.      bls.s    .129
  827.   ;---Store this Event's time in our variables
  828. .131 move.l   d0,10(a3)
  829.      move.l   d1,6(a3)
  830.   ;---Make our own copy of the event in the EventRing buffer
  831.      moveq    #11-1,d0     ;size of an amiga InputEvent = 22 bytes, but we
  832.      movea.l  a2,a1        ;can copy a WORD at a time with even addresses.
  833.      movea.l  (a3),a0      ;get current address within EventRing
  834. cpyE move.w   (a1)+,(a0)+
  835.      Dbra     d0,cpyE
  836.   ;---Indicate that there's one more item in the EventRing buffer
  837.      addq.b   #1,4(a3)     ;Counter
  838.   ;---Check for buffer wrap (at the end of EventRing?)
  839.      move.l   a3,d0        ;end of EventRing
  840.      sub.l    a0,d0
  841.      bhi.s    .134
  842.      lea      _EventRing,a0
  843.   ;---Save next address within EventRing
  844. .134 move.l   a0,(a3)
  845. ;---Is the main task's big_loop asleep?
  846.      Bclr.b   #0,5(a3)      ;Waiting
  847.      beq.s    .136
  848.   ;---If so, wake up main
  849.      move.l   14(a3),d0     ;MainSigMask
  850.      movea.l  _ThisTask,a1
  851.      jsr      _LVOSignal(a6)
  852. ; The buffer may fill eventually. In case that happens, do some waits
  853. ; to give the main task some time to empty the buffer a bit. A completely
  854. ; busy loop would tie up the system forever.
  855. .136 moveq    #47,d0
  856.      sub.b    4(a3),d0
  857.      bcc.s    .129
  858.      move.l   a6,-(sp)
  859.      movea.l  _GfxBase,a6
  860.      jsr      _LVOWaitTOF(a6)
  861.      jsr      _LVOWaitTOF(a6)
  862.      jsr      _LVOWaitTOF(a6)
  863.      movea.l  (sp)+,a6
  864.      bra.s    .136
  865.    ;---Get Event's ie_NextEvent (i.e. the next InputEvent in the list)
  866. .129 movea.l  (a2),a2
  867.    ;---any more events?
  868.      move.l   a2,d0
  869.      bne.s    .128        ;go back if more
  870.    ;  jsr      _LVOPermit(a6)
  871.      movem.l  (sp)+,a0/a2/a3/a6
  872.    ;----return EventChain
  873.      move.l   a0,d0
  874.      rts
  875.  
  876.    SECTION TypeTellData,DATA
  877.  
  878. INPUT_RING_SIZE equ 50    ;# of InputEvents that can fit in EventRing buffer
  879. QUIT_CODE_1     equ $8099 ;Control-shift-alt-alt's event qualifier
  880. QUIT_CODE_2     equ $809d ;As above but with Caps-Lock ON
  881.  
  882.    XDEF   _InputDevPort,_InputRequestBlock,DevicesOpen
  883. _InputDevPort      dc.l 0 ;address of replyPort for input device
  884. _InputRequestBlock dc.l 0 ;address of IOB for input device
  885.  
  886. ;----Interrupt Structure for event_handler routine------
  887.    XDEF handlerInt
  888. handlerInt  dc.l 0,0                   ;to maintain a linked list
  889.             dc.b 2,51                  ;LN_TYPE, LN_PRIORITY
  890.             dc.l 0                     ;LN_NAME
  891.             dc.l currentBuf            ;IS_DATA
  892.             dc.l event_handler         ;IS_CODE
  893.  
  894.  ;These must be in this order
  895.    XDEF   currentBuf,_Emptier,Counter,lastsecond,lastmicro,_EventRing
  896.    XDEF   _MainSignal,_Waiting,MainSigMask
  897.    XDEF   _TranslatorBase,_ConsoleDevice,_GfxBase
  898. ;Raw key events buffer that can hold up to 50 InputEvents (of 22 bytes each)
  899. _EventRing  ds.b 1100
  900. currentBuf  dc.l _EventRing  ;for event_handler()
  901. Counter     dc.b 0           ;for both event_handler() and main()
  902. _Waiting    dc.b 0           ;set by main() before going to sleep
  903. lastsecond  dc.l 0
  904. lastmicro   dc.l 0           ;For event_handler() routine
  905. MainSigMask dc.l 0           ;for event_handler to wake up main()
  906. _Emptier    dc.w 0           ;for main()
  907. DevicesOpen dc.b 0
  908. _MainSignal dc.b $FF
  909. _GfxBase        dc.l 0
  910. _TranslatorBase dc.l 0
  911. _ConsoleDevice  dc.l 0
  912.  
  913.    XDEF   _WriteNarrator,_WritePort
  914. _WriteNarrator      dc.l 0  ;IOB for narrator device
  915. _WritePort          dc.l 0  ;output port for narrator device
  916.  
  917.    XDEF   _AudioChannels
  918. _AudioChannels:
  919.    dc.b   3,5,10,12
  920.  
  921. ;Translated output string buffer
  922. _OutputString ds.b 100
  923. rawkeyBuf     ds.b 30
  924. InputName   dc.b 'input.device',0
  925. GfxName     dc.b 'graphics.library',0
  926. TransName   dc.b 'translator.library',0
  927. ConsoleName dc.b 'console.device',0
  928. NarrDevName dc.b 'narrator.device',0
  929. CAPSON      dc.b 'CAPS LOCK ON',0
  930. CAPSOFF     dc.b 'CAPS LOCK OFF',0
  931. GODOWN      dc.b 'GO DOWN',0
  932. GORIGHT     dc.b 'GO RIGHT',0
  933. GOLEFT      dc.b 'GO LEFT',0
  934. GOUP        dc.b 'GO UP',0
  935. HELP        dc.b 'HELP',0
  936. CONTROL     dc.b 'CONTROL',0
  937. SHIFT       dc.b 'SHIFT',0
  938. RIGHTAMG    dc.b 'RIGHT AMIGA',0
  939. LEFTAMG     dc.b 'LEFT AMIGA',0
  940. ALTERNATE   dc.b 'ALTERNATE',0
  941. F10         dc.b 'FUNCTION TEN',0
  942. F9          dc.b 'FUNCTION NINE',0
  943. F8          dc.b 'FUNCTION EIGHT',0
  944. F7          dc.b 'FUNCTION SEVEN',0
  945. F6          dc.b 'FUNCTION SIX',0
  946. F5          dc.b 'FUNCTION FIVE',0
  947. F4          dc.b 'FUNCTION FOUR',0
  948. F3          dc.b 'FUNCTION THREE',0
  949. F2          dc.b 'FUNCTION TWO',0
  950. F1          dc.b 'FUNCTION ONE',0
  951. ESCAPE      dc.b 'ESCAPE',0
  952. EXCLAM      dc.b 'EXCLAMATION',0
  953. DQ          dc.b 'DOUBLE QUOTE',0
  954. SHARP       dc.b 'SHARP',0
  955. SPACE       dc.b 'SPACE',0
  956. DOLLAR      dc.b 'DOLLAR',0
  957. PERCENT     dc.b 'PERCENT',0
  958. VBAR        dc.b 'VERTICAL BAR',0
  959. RBRACE      dc.b 'RIGHT BRACE',0
  960. LBRACE      dc.b 'LEFT BRACE',0
  961. TILDA       dc.b 'TILDA',0
  962. DEL         dc.b 'DELETE',0
  963. LQUOTE      dc.b 'LEFT QUOTE',0
  964. SCORE       dc.b 'UNDER SCORE',0
  965. CARROT      dc.b 'CARROT',0
  966. RBRACK      dc.b 'RIGHT BRACKET',0
  967. BS          dc.b 'BACKSPACE',0
  968. BSLASH      dc.b 'BACKSLASH',0
  969. QUES        dc.b 'QUESTION',0
  970. AT          dc.b 'AT',0
  971. LBRACK      dc.b 'LEFT BRACKET',0
  972. SCOLON      dc.b 'SEMI COLON',0
  973. EQUAL       dc.b 'EQUAL',0
  974. GREAT       dc.b 'GREATER THAN',0
  975. LESS        dc.b 'LESS THAN',0
  976. COLON       dc.b 'COLON',0
  977. SLASH       dc.b 'SLASH',0
  978. DOT         dc.b 'DOT',0
  979. STAR        dc.b 'STAR',0
  980. PLUS        dc.b 'PLUS',0
  981. MYNUS       dc.b 'MYNUS',0
  982. COMMA       dc.b 'COMMA',0
  983. RP          dc.b 'RIGHT PARENTHESIS',0
  984. LP          dc.b 'LEFT PARENTHESIS',0
  985. AND         dc.b 'AND',0
  986. RQUOTE      dc.b 'RIGHT QUOTE',0
  987.  
  988.    END
  989.